package com.mtw.bbs.bbsUser.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.github.wujun234.uid.impl.CachedUidGenerator;
import com.mtw.bbs.bbsUser.constant.Constant;
import com.mtw.bbs.bbsUser.constant.EUser;
import com.mtw.bbs.bbsUser.pojo.elasticsearch.UserESIndex;
import com.mtw.bbs.bbsUser.pojo.form.PasswordForm;
import com.mtw.bbs.bbsUser.pojo.form.UserForm;
import com.mtw.bbs.bbsUser.pojo.form.UserUpdateForm;
import com.mtw.bbs.bbsUser.repository.UserESRepository;
import com.mtw.bbs.bbsUser.service.UserRoleService;
import com.mtw.bbs.common.core.constant.ServiceConstant;
import com.mtw.bbs.common.core.exception.BusinessException;
import com.mtw.bbs.common.core.security.UserDetails;
import com.mtw.bbs.common.core.security.context.SecurityContextHolder;
import com.mtw.bbs.common.core.util.CommonUtil;
import com.mtw.bbs.common.redisBase.util.RedisUtilz;
import com.mtw.bbs.common.redisBase.util.TimeUtilz;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.mtw.bbs.bbsUser.mapper.UserMapper;
import com.mtw.bbs.bbsUser.pojo.entity.User;
import com.mtw.bbs.bbsUser.service.UserService;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static com.mtw.bbs.bbsUser.constant.EUser.DEFAULT_ADMIN_PWD;

/**
 * 用户逻辑层
 * @author mo
 * @email mo
 * @date 2023-10-18 15:44:13
 */
@Service("userService")
@RequiredArgsConstructor
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {

    private final UserMapper userMapper;
    private final UserRoleService userRoleService;
    private final UserESRepository userESRepository;
    private final RedisUtilz<String,User> redisUtilz;
    private final CachedUidGenerator cachedUidGenerator;



    /**
     * 根据用户获取用户信息
     *
     * @param username 用户名
     * @return 用户信息vo
     */
    @Override
    public User getUserInfoByUsername(String username) {


        String key = Constant.USERR_NAME_KEY + username;
        User user = redisUtilz.get(key);
        if (user == null) {
            user = userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername,username));
            if (user == null){
                return null;
            }
            user.setPassword(null);

            redisUtilz.set(key,user, Duration.ofSeconds(300+ TimeUtilz.getRandomSecond()));
        }
        return user;
    }


    /**
     * 根据用户id获取用户信息
     *
     * @param id 用户id
     * @return 用户信息vo
     */
    @Override
    public User getUserInfoById(String id) {

        String key = Constant.USERR_ID_KEY + id;
        User user = redisUtilz.get(key);
        if (user == null) {
            user = userMapper.selectById(id);
            if (user == null){
                return null;
            }
            user.setPassword(null);

            redisUtilz.set(key,user, Duration.ofSeconds(300+ TimeUtilz.getRandomSecond()));
        }
        return user;

    }


    /**
     * 根据用户id集合获取用户信息
     *
     * @param ids 用户id集合
     * @return 用户信息vo集合
     */
    @Override
    public List<User> getUserInfoByIds(List<String> ids) {

        if (CollectionUtils.isEmpty(ids)) {
            return new ArrayList<>();
        }
        return ids.stream().map(this::getUserInfoById).filter(Objects::nonNull).toList();
    }


    /**
     * 根据用户名获取用户全部信息
     *
     * @param username 用户名
     * @return 用户信息
     */
    @Override
    public User loadUserByUserName(String username) {
        return userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getUsername, username));
    }


    /**
     * 根据mobile获取用户
     *
     * @param mobile 用户手机号
     * @return 用户信息
     */
    @Override
    public User loadUserByMobile(String mobile) {
        return userMapper.selectOne(new LambdaQueryWrapper<User>().eq(User::getPhone, mobile));
    }


    /**
     * 修改密码
     *
     * @param id          用户id
     * @return 结果
     */
    @Override
    public boolean updatePassword(String id, PasswordForm form) {

        User user = getOne(new LambdaQueryWrapper<User>().eq(User::getId, id));

        if (!user.getPassword().equals(CommonUtil.getMD5(form.getOldPassword()))) {
            throw new BusinessException("密码不正确!");
        }

        LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
        luw.set(User::getPassword, CommonUtil.getMD5(form.getNewPassword()));
        luw.eq(User::getId, id);
        return this.update(luw);
    }


    /**
     * 注册用户
     */
    @Override
    @Transactional
    public void registerUser(User user) {

        if (StringUtils.isNotBlank(user.getDisplayName())){
            LambdaQueryWrapper<User> dlqw = new LambdaQueryWrapper<>();
            dlqw.eq(User::getDisplayName,user.getDisplayName());
            if (count(dlqw) > 0){
                throw new BusinessException("当前昵称已被使用!");
            }
        }

        if (StringUtils.isNotBlank(user.getPhone())) {
            LambdaQueryWrapper<User> plqw = new LambdaQueryWrapper<>();
            plqw.eq(User::getPhone,user.getPhone());
            if (count(plqw) > 0){
                throw new BusinessException("当前手机号已被使用!");
            }
        }

        if (StringUtils.isNotBlank(user.getEmail())) {
            LambdaQueryWrapper<User> elqw = new LambdaQueryWrapper<>();
            elqw.eq(User::getEmail,user.getEmail());
            if (count(elqw) > 0){
                throw new BusinessException("当前邮箱已被使用!");
            }
        }
        user.setUserType(EUser.USER);
        user.setStatus(ServiceConstant.STATUS_ENABLE);
        user.setUsername(String.valueOf(cachedUidGenerator.getUID()));
        user.setPassword(CommonUtil.getMD5(user.getPassword()));
        userMapper.insert(user);

        // 保存进ES
        this.updateES(user);

    }


    /**
     * 注册管理员用户
     */
    @Override
    @Transactional
    public void registerAdmin(UserForm form) {

        if (StringUtils.isNotBlank(form.getDisplayName())){
            LambdaQueryWrapper<User> dlqw = new LambdaQueryWrapper<>();
            dlqw.eq(User::getDisplayName,form.getDisplayName());
            if (count(dlqw) > 0){
                throw new BusinessException("当前昵称已被使用!");
            }
        }

        if (StringUtils.isNotBlank(form.getPhone())) {
            LambdaQueryWrapper<User> plqw = new LambdaQueryWrapper<>();
            plqw.eq(User::getPhone,form.getPhone());
            if (count(plqw) > 0){
                throw new BusinessException("当前手机号已被使用!");
            }
        }

        if (StringUtils.isNotBlank(form.getEmail())) {
            LambdaQueryWrapper<User> elqw = new LambdaQueryWrapper<>();
            elqw.eq(User::getEmail,form.getEmail());
            if (count(elqw) > 0){
                throw new BusinessException("当前邮箱已被使用!");
            }
        }
        User user = new User();
        BeanUtils.copyProperties(form,user);
        user.setUserType(EUser.ADMIN);
        user.setUsername(String.valueOf(cachedUidGenerator.getUID()));
        user.setPassword(CommonUtil.getMD5(DEFAULT_ADMIN_PWD));
        save(user);
        if (!CollectionUtils.isEmpty(form.getRole())){
            userRoleService.saveBatch(user.getId(),form.getRole());
        }
    }


    /**
     * 更新管理员用户
     */
    @Override
    @Transactional
    public void updateAdmin(UserForm form) throws BusinessException {

        updateUser(form);
        userRoleService.removeByUserId(form.getId());
        if (!CollectionUtils.isEmpty(form.getRole())){
            userRoleService.saveBatch(form.getId(),form.getRole());
        }
    }


    /**
     * 更新用户
     */
    @Override
    public boolean updateUser(UserForm form) {

        if (StringUtils.isNotBlank(form.getDisplayName())){
            LambdaQueryWrapper<User> dlqw = new LambdaQueryWrapper<>();
            dlqw.ne(User::getId,form.getId());
            dlqw.eq(User::getDisplayName,form.getDisplayName());
            if (count(dlqw) > 0){
                throw new BusinessException("当前昵称已被使用!");
            }
        }

        if (StringUtils.isNotBlank(form.getPhone())) {
            LambdaQueryWrapper<User> plqw = new LambdaQueryWrapper<>();
            plqw.ne(User::getId,form.getId());
            plqw.eq(User::getPhone,form.getPhone());
            if (count(plqw) > 0){
                throw new BusinessException("当前手机号已被使用!");
            }
        }

        if (StringUtils.isNotBlank(form.getEmail())) {
            LambdaQueryWrapper<User> elqw = new LambdaQueryWrapper<>();
            elqw.ne(User::getId,form.getId());
            elqw.eq(User::getEmail,form.getEmail());
            if (count(elqw) > 0){
                throw new BusinessException("当前邮箱已被使用!");
            }
        }

        User user = userMapper.selectById(form.getId());
        BeanUtils.copyProperties(form,user);

        boolean result = updateById(user);
        if (result){
            redisUtilz.delete(Constant.USERR_ID_KEY + user.getId());
            redisUtilz.delete(Constant.USERR_NAME_KEY + user.getUsername());

            // 更新ES
            this.updateES(user);
        }
        return result;
    }


    /**
     * 更新用户信息
     */
    @Override
    public String updateUserInfo(UserUpdateForm form) {

        UserDetails userDetails = SecurityContextHolder.getContext().getAuthentication();

        if (StringUtils.isBlank(form.getUpdateType())){
            return "修改失败";
        }

        User user = userMapper.selectById(userDetails.getId());

        LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
        luw.eq(User::getId,userDetails.getId());
        switch (form.getUpdateType()){
            case "1":
                if (StringUtils.isBlank(form.getAvatar())){
                    return "修改失败";
                }
                luw.set(User::getAvatar,form.getAvatar());
                user.setAvatar(form.getAvatar());
                break;
            case "2":
                if (StringUtils.isBlank(form.getDisplayName())){
                    return "修改失败";
                }
                LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
                lqw.ne(User::getId,userDetails.getId());
                lqw.eq(User::getDisplayName,form.getDisplayName());
                long count = this.count(lqw);
                if (count >0){
                    return "修改失败";
                }
                luw.set(User::getDisplayName,form.getDisplayName());
                user.setDisplayName(form.getDisplayName());
                break;
            case "3":
                if (form.getSex() == null){
                    return "修改失败";
                }
                luw.set(User::getSex,form.getSex());
                break;
            case "4":
                if (StringUtils.isBlank(form.getConstellation()) || form.getBirthday() == null){
                    return "修改失败";
                }
                luw.set(User::getBirthday,form.getBirthday());
                luw.set(User::getConstellation,form.getConstellation());
                break;
            case "5":
                luw.set(User::getIntroduction,form.getIntroduction());
                break;
            case "6":
                luw.set(User::getAddress,form.getAddress());
                break;
            default:
                break;
        }
        boolean updated = this.update(luw);
        if (updated){
            redisUtilz.delete(Constant.USERR_ID_KEY + userDetails.getId());
            redisUtilz.delete(Constant.USERR_NAME_KEY + userDetails.getUsername());

            // 更新ES
            this.updateES(user);
        }
        return null;
    }


    /**
     * 更新es
     */
    private void updateES(User user) {

        // 保存进ES
        UserESIndex esIndex = new UserESIndex();
        esIndex.setId(user.getId());
        esIndex.setUsername(user.getUsername());
        esIndex.setDisplayName(user.getDisplayName());
        esIndex.setAvatar(user.getAvatar());
        esIndex.setStatus(user.getStatus());
        esIndex.setSex(user.getSex());
        esIndex.setUserType(user.getUserType());

        userESRepository.save(esIndex);
    }

    /**
     * 更新用户状态
     *
     * @param ids     用户id集合
     * @param status 用户状态
     */
    @Override
    public void updateUserStatus(List<String> ids, Integer status) {
        if (!CollectionUtils.isEmpty(ids)) {
            LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
            luw.set(User::getStatus, status);
            luw.in(User::getId, ids);
            update(luw);
        }

    }


    /**
     * 更新用户评论状态
     *
     * @param ids     用户id集合
     * @param status  评论状态
     */
    @Override
    public void updateCommentStatus(List<String> ids, Integer status) {
        if (!CollectionUtils.isEmpty(ids)) {
            LambdaUpdateWrapper<User> luw = new LambdaUpdateWrapper<>();
            luw.set(User::getCommentStatus, status);
            luw.in(User::getId, ids);
            update(luw);
        }
    }


}
